package com.unittec.zk.provider.auth.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.unittec.zk.provider.auth.dto.LoginRevertInfo;
import com.unittec.zk.provider.auth.dto.UserInfo;
import com.unittec.zk.provider.auth.entity.SysRole;
import com.unittec.zk.provider.auth.entity.SysUser;
import com.unittec.zk.provider.common.JwtTokenUtil;
import com.unittec.zk.provider.common.RedisUtils;
import com.unittec.zk.provider.log.Log;
import com.unittec.zk.provider.utils.PasswordUtil;
import com.unittec.zk.provider.utils.RSAUtil;
import com.unittec.zk.provider.utils.SmsUtil;
import com.unittec.zk.sdk.auth.request.Req101703;
import com.unittec.zk.sdk.auth.response.Res101703;
import com.unittec.zk.sdk.root.common.CommonConstant;
import com.unittec.zk.sdk.root.domain.GatewayRequest;
import com.unittec.zk.sdk.root.enums.BizCode;
import com.unittec.zk.sdk.root.enums.BizCodeEnum;
import com.unittec.zk.sdk.root.internal.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class LoginService {

    @Autowired
    Log log;

    @Value("${sms.templateList.verificationCode}")
    private String templateId;

    @Value("${rsa.privateKey}")
    private String privateKey;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    private SmsUtil smsUtil;

    public BizCodeEnum sendSmsCode(String phone, String code) {
        BizCodeEnum bizCodeEnum = BizCode.ERROR;
        SysUser sysUser = sysUserService.findUserByPhone(phone);
        if (sysUser == null) {
            bizCodeEnum = BizCode.NOT_PHONE;
        } else {
            String codeTime = redisUtils.get(CommonConstant.LOGIN_VERIFICATION_CODE_TIME + phone);
            if (codeTime == null) {
                JSONObject smsParamJson = new JSONObject();
                smsParamJson.put("code", code);
                JSONObject json = smsUtil.sendSms(phone, smsParamJson, templateId);
                if ("00000".equals(json.getString("code"))) {
                    redisUtils.set(CommonConstant.LOGIN_VERIFICATION_CODE + phone, code, 180L);
                    redisUtils.set(CommonConstant.LOGIN_VERIFICATION_CODE_TIME + phone, code, 60L);
                    bizCodeEnum = BizCode.SUCCESS;
                } else {
                    bizCodeEnum = BizCode.VERIFICATION_CODE_SEND_ERROR;
                }
            } else {
                bizCodeEnum = BizCode.VERIFICATION_CODE_REPEAT_SEND;
            }
        }
        return bizCodeEnum;
    }

    public LoginRevertInfo login(GatewayRequest<Req101703> req) {
        LoginRevertInfo loginRevertInfo = null;
        if (req.getContent().getLoginType().equals(CommonConstant.LOGIN_TYPE_1)) {
            loginRevertInfo = usernameLogin(req);
        } else {
            loginRevertInfo = phoneLogin(req);
        }
        return loginRevertInfo;
    }

    public LoginRevertInfo usernameLogin(GatewayRequest<Req101703> req) {
        LoginRevertInfo loginRevertInfo = new LoginRevertInfo();
        BizCodeEnum bizCodeEnum = BizCode.ERROR;
        Res101703 res101703 = new Res101703();
        UserInfo userInfo = sysUserService.getUserInfoByUsername(req.getContent().getUserName());
        if (ObjectUtils.isNotEmpty(userInfo)) {
            if (userInfo.getPlatformCode().indexOf(req.getAppId()) != -1) {
                if (userInfo.getDelFlag().equals(CommonConstant.DELETE_NO)) {
                    if (userInfo.getStatus().equals(CommonConstant.STATUS_0)) {
                        String password = "";
                        try {
                            password = RSAUtil.decryptByPrivateKey(req.getContent().getPassword(), privateKey);
                        } catch (Exception e) {
                            log.error(req, "登录密码私钥解密失败", e);
                            throw new BusinessException("登录密码私钥解密失败");
                        }
                        if (userInfo.getPassword().equals(PasswordUtil.encrypt(req.getContent().getUserName(), password, userInfo.getSalt()))) {
                            String token = "";
                            try {
                                token = JwtTokenUtil.createToken(userInfo.getId(), userInfo.getUsername(), userInfo.getTenantId(), req.getAppKey(), req.getAppId());
                                res101703.setToken(token);
                                res101703.setUserId(userInfo.getId());
                                res101703.setUsername(userInfo.getUsername());
                                res101703.setRealname(userInfo.getRealname());
                                res101703.setAvatar(userInfo.getAvatar());
                                res101703.setUserType(userInfo.getType());
                                res101703.setPlatformCode(userInfo.getPlatformCode());
                                res101703.setTenantId(userInfo.getTenantId());
                                Boolean isAdmin = Boolean.FALSE;
                                List<SysRole> roleList = sysUserRoleService.getSysRoleByUserId(userInfo.getId());
                                if (roleList != null && roleList.size() > 0) {
                                    StringBuilder userRole = new StringBuilder();
                                    StringBuilder userRoleId = new StringBuilder();
                                    for (int i = 0; i < roleList.size(); i++) {
                                        SysRole sysRole = roleList.get(i);
                                        if (sysRole.getRoleCode().equalsIgnoreCase(CommonConstant.ADMIN_ROLE_CODE)) {
                                            isAdmin = Boolean.TRUE;
                                        }
                                        if (i != 0) {
                                            userRole.append("," + sysRole.getRoleCode());
                                            userRoleId.append("," + sysRole.getId());
                                        } else {
                                            userRole.append(sysRole.getRoleCode());
                                            userRoleId.append(sysRole.getId());
                                        }
                                    }
                                    res101703.setUserRole(userRole.toString());
                                    res101703.setUserRoleId(userRoleId.toString());
                                }
                                res101703.setIsAdmin(isAdmin);
                                bizCodeEnum = BizCode.SUCCESS;
                            } catch (Exception e) {
                                log.error(req, e.toString(), e);
                                bizCodeEnum = BizCode.TOKEN_GENERATION_FAILURE;
                            }
                        } else {
                            bizCodeEnum = BizCode.USER_PASSWORD_ERROR;
                        }
                    } else {
                        bizCodeEnum = BizCode.USER_FREEZE;
                    }
                } else {
                    bizCodeEnum = BizCode.USER_DELETE;
                }
            } else {
                bizCodeEnum = BizCode.NO_PERMISSION_TO_LOG_IN_TO_THE_PLATFORM;
            }
        } else {
            bizCodeEnum = BizCode.NOT_USER;
        }
        loginRevertInfo.setBizCodeEnum(bizCodeEnum);
        loginRevertInfo.setRes101703(res101703);
        loginRevertInfo.setUserInfo(userInfo);
        return loginRevertInfo;
    }

    public LoginRevertInfo phoneLogin(GatewayRequest<Req101703> req) {
        LoginRevertInfo loginRevertInfo = new LoginRevertInfo();
        BizCodeEnum bizCodeEnum = BizCode.ERROR;
        Res101703 res101703 = new Res101703();
        UserInfo userInfo = sysUserService.getUserInfoByPhone(req.getContent().getPhone());
        if (ObjectUtils.isNotEmpty(userInfo)) {
            if (userInfo.getPlatformCode().indexOf(req.getAppId()) != -1) {
                if (userInfo.getDelFlag().equals(CommonConstant.DELETE_NO)) {
                    if (userInfo.getStatus().equals(CommonConstant.STATUS_0)) {
                        String code = redisUtils.get(CommonConstant.LOGIN_VERIFICATION_CODE + req.getContent().getPhone());
                        if (code != null) {
                            if (code.equals(req.getContent().getCode())) {
                                try {
                                    String token = JwtTokenUtil.createToken(userInfo.getId(), userInfo.getUsername(), userInfo.getTenantId(), req.getAppKey(), req.getAppId());
                                    res101703.setToken(token);
                                    res101703.setUserId(userInfo.getId());
                                    res101703.setUsername(userInfo.getUsername());
                                    res101703.setRealname(userInfo.getRealname());
                                    res101703.setAvatar(userInfo.getAvatar());
                                    res101703.setUserType(userInfo.getType());
                                    res101703.setPlatformCode(userInfo.getPlatformCode());
                                    res101703.setTenantId(userInfo.getTenantId());
                                    Boolean isAdmin = Boolean.FALSE;
                                    List<SysRole> roleList = sysUserRoleService.getSysRoleByUserId(userInfo.getId());
                                    if (roleList != null && roleList.size() > 0) {
                                        StringBuilder userRole = new StringBuilder();
                                        StringBuilder userRoleId = new StringBuilder();
                                        for (int i = 0; i < roleList.size(); i++) {
                                            SysRole sysRole = roleList.get(i);
                                            if (sysRole.getRoleCode().equalsIgnoreCase(CommonConstant.ADMIN_ROLE_CODE)) {
                                                isAdmin = Boolean.TRUE;
                                            }
                                            if (i != 0) {
                                                userRole.append("," + sysRole.getRoleCode());
                                                userRoleId.append("," + sysRole.getId());
                                            } else {
                                                userRole.append(sysRole.getRoleCode());
                                                userRoleId.append(sysRole.getId());
                                            }
                                        }
                                        res101703.setUserRole(userRole.toString());
                                        res101703.setUserRoleId(userRoleId.toString());
                                    }
                                    res101703.setIsAdmin(isAdmin);
                                    bizCodeEnum = BizCode.SUCCESS;
                                } catch (Exception e) {
                                    log.error(req, e.toString(), e);
                                    bizCodeEnum = BizCode.TOKEN_GENERATION_FAILURE;
                                }
                            } else {
                                bizCodeEnum = BizCode.USER_PHONE_CODE_ERROR;
                            }
                        } else {
                            bizCodeEnum = BizCode.USER_PHONE_CODE_EXPIRE;
                        }
                    } else {
                        bizCodeEnum = BizCode.USER_FREEZE;
                    }
                } else {
                    bizCodeEnum = BizCode.USER_DELETE;
                }
            } else {
                bizCodeEnum = BizCode.NO_PERMISSION_TO_LOG_IN_TO_THE_PLATFORM;
            }
        } else {
            bizCodeEnum = BizCode.NOT_USER;
        }
        loginRevertInfo.setBizCodeEnum(bizCodeEnum);
        loginRevertInfo.setRes101703(res101703);
        loginRevertInfo.setUserInfo(userInfo);
        return loginRevertInfo;
    }

}
